
# 从qtpy库的QtWidgets模块导入QMenu类，用于创建菜单
from qtpy.QtWidgets import QMenu


class ContextMenuGenerator(object):
    """
    ContextMenuGenerator类用于根据提供的菜单数据生成上下文菜单。

    :param menuDataBuilder: 一个对象，包含获取菜单数据的方法get()
    """

    def __init__(self, menuDataBuilder):
        """
        初始化ContextMenuGenerator类的实例。

        :param menuDataBuilder: 一个对象，包含获取菜单数据的方法get()
        """
        super(ContextMenuGenerator, self).__init__()
        # 存储菜单数据构建器对象
        self.builder = menuDataBuilder

    def __createMenuEntry(self, parentMenu, menuEntryData):
        """
        递归地在父菜单中创建菜单项。

        :param parentMenu: 父菜单对象，用于添加新的菜单项或子菜单
        :param menuEntryData: 包含菜单项信息的字典，可能包含标题、图标、回调函数和子菜单数据
        """
        # 检查菜单条目数据中是否包含分隔符标识
        if "separator" in menuEntryData:
            # 如果包含，则在父菜单中添加分隔符
            parentMenu.addSeparator()
            return
        # 从菜单条目数据中获取图标
        icon = menuEntryData["icon"]
        # 检查菜单条目数据中是否包含子菜单标识
        if "sub_menu" in menuEntryData:
            # 如果包含，则获取子菜单数据
            subMenuData = menuEntryData["sub_menu"]
            # 在父菜单中添加一个新的子菜单，并设置标题
            subMenu = parentMenu.addMenu(menuEntryData["title"])
            # 如果图标不为空，则为子菜单设置图标
            if icon is not None:
                subMenu.setIcon(icon)
            # 递归调用__createMenuEntry方法，处理子菜单数据
            self.__createMenuEntry(subMenu, subMenuData)
        else:
            # 如果不包含子菜单，则在父菜单中添加一个动作项，并设置标题
            action = parentMenu.addAction(menuEntryData["title"])
            # 如果图标不为空，则为动作项设置图标
            if icon is not None:
                action.setIcon(icon)
            # 将动作项的触发信号连接到菜单条目数据中的回调函数
            action.triggered.connect(menuEntryData["callback"])

    def generate(self):
        """
        根据菜单数据构建器生成上下文菜单。

        :return: 生成好的QMenu对象
        """
        # 调用菜单数据构建器的get方法获取菜单数据
        menuData = self.builder.get()
        # 创建一个新的QMenu对象
        menu = QMenu()
        # 遍历菜单数据中的每个菜单项
        for menuEntry in menuData:
            # 调用__createMenuEntry方法，在菜单中创建菜单项
            self.__createMenuEntry(menu, menuEntry)
        return menu